/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.xadrez.ia;

import com.xadrez.exception.NumeroDeJogadorExcessoException;
import com.xadrez.exception.PecaProibidaException;
import com.xadrez.modelo.Peao;
import com.xadrez.modelo.Peca;
import com.xadrez.modelo.Posicao;
import com.xadrez.modelo.Rainha;
import com.xadrez.modelo.Rei;
import com.xadrez.modelo.Tabuleiro;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author fabricio
 */
public class TabuleiroIA extends Tabuleiro implements Cloneable, Comparable<TabuleiroIA> {

    private Jogada jogada;
    public ArrayList<Peca> pecasJogador1, pecasJogador2;
    private int peso;
//    public static int cont = 0; 

    public TabuleiroIA(Tabuleiro tabuleiro) throws NumeroDeJogadorExcessoException {
        super(tabuleiro.getJogadorUm(), tabuleiro.getJogadorDois());
        this.setStatus(tabuleiro.getStatus());
        this.setJogadorDaVez(tabuleiro.getJogadorDaVez());
        // ao receber a cópia do tabuleiro resta acertar os outros parametros.
        this.setQuadrados(new Peca[8][8]);
        this.jogada = null;
        this.pecasJogador1 = new ArrayList<Peca>();
        this.pecasJogador2 = new ArrayList<Peca>();

        // Adiciona as peças no array de 
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (tabuleiro.getQuadrados()[i][j] != null) {
                    this.getQuadrados()[i][j] = tabuleiro.getQuadrados()[i][j].clone();
                    if (this.getQuadrados()[i][j].getJogador().getId() == 1) {
                        this.pecasJogador1.add(this.getQuadrados()[i][j]);
                    } else {
                        this.pecasJogador2.add(this.getQuadrados()[i][j]);
                    }
                }
            }
        }

    }

    public boolean hasJogadas() {

        for (Peca peca : this.getPecasJogador(getJogadorDaVez().getId())) {
            if (!(peca.recuperaMovimentosPossiveis().isEmpty())) {
                return true;
            }
        }


        return false;

    }

    public int getIdDaVez() {
        return getJogadorDaVez().getId();
    }

    @Override
    public Tabuleiro clone() {

        TabuleiroIA tab = (TabuleiroIA) super.clone();
        tab.jogada = this.jogada;

        tab.pecasJogador1 = new ArrayList<Peca>();
        tab.pecasJogador2 = new ArrayList<Peca>();
        // Adiciona as peças no array de 
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (tab.getQuadrados()[i][j] != null) {
                    if (this.getQuadrados()[i][j].getJogador().getId() == 1) {
                        tab.pecasJogador1.add(tab.getQuadrados()[i][j]);
                    } else {
                        tab.pecasJogador2.add(tab.getQuadrados()[i][j]);
                    }
                }
            }
        }

        return tab;
    }

    public void setJogada(Jogada jogada) {
        if (this.jogada == null) {
            this.jogada = jogada;
        }
    }

    public Jogada getJogada() {
        return jogada;
    }

    // Colocar aqui a critica do motor
    public void Mover(Peca peca, Posicao destino) {

        Posicao posicao = peca.getPosicaoNoTabuleiro();
        Peca pecaAux = this.getQuadrados()[posicao.getX()][posicao.getY()];
        Peca pecaComida = this.getQuadrados()[destino.getX()][destino.getY()];
        pecaAux.deslocaPeca(destino);
        if (pecaComida != null) {
            this.remove(getJogadorAdversario().getId(), pecaComida);
        }
        if (pecaAux instanceof Peao) {
            if (((Peao) pecaAux).upar()) {
                try {
                    this.promocao(pecaAux, Rainha.class);
                } catch (PecaProibidaException ex) {
                    Logger.getLogger(TabuleiroIA.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InstantiationException ex) {
                    Logger.getLogger(TabuleiroIA.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IllegalAccessException ex) {
                    Logger.getLogger(TabuleiroIA.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }

        setJogadorDaVez(getJogadorAdversario());
//        this.desenha();
    }

    public ArrayList<Peca> getPecasJogador(int num) {
        if (num == 1) {
            return pecasJogador1;
        } else if (num == 2) {
            return pecasJogador2;
        } else {
            return null; // impleentar um trows
        }
    }

    public void setPecasJogador(int num, ArrayList<Peca> list) {
        if (num == 1) {
            pecasJogador1 = list;
        } else if (num == 2) {
            pecasJogador2 = list;
        }
    }

    public int getPeso() {
        return peso;
    }

    public void setPeso(int peso) {
        this.peso = peso;
    }

    public int compareTo(TabuleiroIA o) {
        if (this.peso == o.peso) {
            return 0;
        } else if (this.peso > o.peso) {
            return 1;
        } else {
            return -1;
        }
    }

// <editor-fold defaultstate="collapsed" desc="ADIÇÃO E REMOÇÃO DE PEÇAS">
    public void add(int num, Peca peca) {
        if (num == 1) {
            pecasJogador1.add(peca);
        } else if (num == 2) {
            pecasJogador2.add(peca);
        }
        //else
        // Propagar um erro
    }

    public void remove(int num, Peca peca) {
        if (num == 1) {
            pecasJogador1.remove(peca);
        } else if (num == 2) {
            pecasJogador2.remove(peca);
        }
        //else
        // propagar um erro
    }
    // </editor-fold>

    @Override
    public Peca promocao(Peca pecaAntiga, Class c) throws PecaProibidaException, InstantiationException, IllegalAccessException {

        Peca pecaNova = (Peca) c.newInstance();
        if ((pecaNova instanceof Peao) || (pecaNova instanceof Rei)) {
            throw new PecaProibidaException("Você não pode evoluir para peão ou um Rei");
        }
        pecaNova.setAtiva(pecaAntiga.isAtiva());
        pecaNova.setJogador(pecaAntiga.getJogador());
        pecaNova.setPosicaoNoTabuleiro(pecaAntiga.getPosicaoNoTabuleiro());
        pecaNova.setTabuleiro(pecaAntiga.getTabuleiro());
        getQuadrados()[pecaAntiga.getPosicaoNoTabuleiro().getX()][pecaAntiga.getPosicaoNoTabuleiro().getY()] = pecaNova;

        if (pecaNova.getJogador().getId() == 1) {
            pecasJogador1.remove(pecaAntiga);
            pecasJogador2.add(pecaNova);
        } else {
            pecasJogador1.remove(pecaAntiga);
            pecasJogador1.add(pecaNova);
        }
        return pecaNova;
    }
}
